package com.example.zyl.common.query.query;

import com.example.zyl.common.query.annotation.ApiDecrypt;
import com.example.zyl.common.query.enums.DecryptAlg;
import com.example.zyl.common.utils.ToolUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public interface BaseDecryptDto {

    Logger log = LoggerFactory.getLogger(BaseDecryptDto.class);

    default void decrypt(Object data) {

        if (ToolUtils.isObjectType(data)) return;

        // 集合类型数据解密
        if (data instanceof Collection) {
            for (Object item : (Collection<?>) data) {
                this.decryptValue(item);
            }
            return;
        }
        this.decryptValue(data);
    }


    default void decrypt(Object data, List<String> fields) {

        if (ToolUtils.isObjectType(data)) return;

        if (ToolUtils.isEmpty(fields)) return;

        if (data instanceof Map) {
            Map<?, ?> map = (Map<?, ?>) data;
            for (String field : fields) {
                Object value = map.get(field);
                if (value != null) {
                    this.decryptValue(value);
                }
            }
        }
    }

    /**
     * 解密单个值
     *
     * @param value 解密值
     */
    default void decryptValue(Object value) {
        if (value == null) return;

        Field[] declaredFields = value.getClass().getDeclaredFields();

        for (Field field : declaredFields) {
            field.setAccessible(true);
            try {
                ApiDecrypt apiDecrypt = field.getAnnotation(ApiDecrypt.class);
                Object o = field.get(value);
                if (apiDecrypt != null) {
                    DecryptAlg alg = apiDecrypt.alg();
                    String key = apiDecrypt.key();
                    String apply = alg.desensitizer().apply(o.toString(), key);
                    field.set(value, apply);
                }
            } catch (IllegalAccessException e) {
                log.error("解密失败", e);
            }
        }
    }

    ;
}
